//初始化头文件
#include <linux/init.h>
//最基本的文件，支持动态添加和卸载模块。
#include <linux/module.h>
//平台设备所需要的头文件
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
#include <linux/ioport.h>
//文件系统头文件，定义文件表结构（file,buffer_head,m_inode 等）
#include <linux/fs.h>
//包含了 copy_to_user、copy_from_user 等内核访问用户进程内存地址的函数定义。
#include <linux/uaccess.h>
//包含了 ioremap、iowrite 等内核访问 IO 内存等函数的定义。
#include <linux/io.h>
//设备树of函数
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_address.h>

// rsource
struct resource *platform_device_mem;
struct resource *platform_device_mem1;

// device_tree匹配不上时使用id_table进行匹配 优先级1
static const struct of_device_id devicetree_platform_of_match[] = {
	{ .compatible = "devicetree_platform", }, 
};

// 该节点匹配不上时使用id_table进行匹配 优先级2
static const struct platform_device_id devicetree_platform_id_table = {
	.name = "device_platform" 
};

static int devicetree_platform_probe(struct platform_device *pdev)
{
	platform_device_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (platform_device_mem == NULL)
	{
		printk("platform_get_resource platform_device_mem is error\n");
		return -1;
	}
	printk("platform_device_res[0] start is 0x%x \n", platform_device_mem->start);
	printk("platform_device_res[0] end is 0x%x \n", platform_device_mem->end);
	printk("platform_device_res[0] name is %s \n", platform_device_mem->name);

	platform_device_mem1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (platform_device_mem1 == NULL)
	{
		printk("platform_get_resource platform_device_mem1 is error\n");
		return -1;
	}
	printk("platform_device_res[1] start is 0x%x \n", platform_device_mem1->start);
	printk("platform_device_res[1] end is 0x%x \n", platform_device_mem1->end);
	printk("platform_device_res[1] name is %s \n", platform_device_mem1->name);

	return 0;
}

static int devicetree_platform_remove(struct platform_device *pdev)
{
	printk("%s %d\n", __FUNCTION__, __LINE__);
	return 0;
}

static struct platform_driver devicetree_platform_driver = {
	.probe		= devicetree_platform_probe,
	.remove		= devicetree_platform_remove,
	.driver		= {
		.name	= "devicetree_platform",  // 优先级3
		.of_match_table = of_match_ptr(devicetree_platform_of_match),
	},
	.id_table 	= &devicetree_platform_id_table	// 该节点匹配不上时使用name属性进行匹配 优先级2
};


/* 1. 入口函数 */
static int __init devicetree_platform_init(void)
{	
	printk("%s %d\n", __FUNCTION__, __LINE__);
	return platform_driver_register(&devicetree_platform_driver);
}


/* 2. 出口函数 */
static void __exit devicetree_platform_exit(void)
{
	printk("%s %d\n", __FUNCTION__, __LINE__);
	platform_driver_unregister(&devicetree_platform_driver);
}

module_init(devicetree_platform_init);
module_exit(devicetree_platform_exit);


MODULE_AUTHOR("Kongjun"); // 作者
MODULE_DESCRIPTION("platform driver"); // 驱动介绍可以不写
MODULE_LICENSE("GPL");// 开源协议